Skip to content

Add lbzip2 2.6.5 - #322

Open
caius72 wants to merge 1 commit into
inikep:masterfrom
caius72:add-lbzip2
Open

Add lbzip2 2.6.5#322
caius72 wants to merge 1 commit into
inikep:masterfrom
caius72:add-lbzip2

Conversation

@caius72

@caius72 caius72 commented Aug 22, 2026

Copy link
Copy Markdown

lbzip2 is a bzip2-compatible compressor. This adds it as lbzip2, levels 1-9, benchmarked single-threaded like the other codecs.

What is vendored

bwt/lbzip2/ holds five sources from lbzip2 2.6.5 — crctab.c, decode.c, divbwt.c, encode.c, parse.c — plus their headers, COPYING (GPL-3.0-or-later) and a README.md recording provenance and how to refresh them. They are byte-for-byte upstream. Upstream's main.c, process.c, compress.c and expand.c are the multi-threaded command-line tool and are not built.

lbzip2_lzbench.c is the lzbench-side wrapper. lbzip2's tool splits work over threads; lzbench benchmarks buffer-to-buffer calls and does its own threading, so the wrapper drives the same low-level codec sequentially, block by block, the way compress.c and expand.c do around lbzip2's scheduler. It also supplies the one function (xmalloc) that decode.c expects from the tool. Registered BENCH_POOL_MT.

Build and portability

  • -Ddivbwt=lbzip2_divbwt: zstd's dictBuilder exports a divbwt() too, which collides at link time. -Dxmalloc=lbzip2_xmalloc pre-empts the same problem with a much more common name. Renaming on the compile line keeps the vendored sources unpatched.
  • bwt/lbzip2/arpa/inet.h is a shim for MinGW, which has no such header; three of the sources include it for ntohl/htonl alone. It is reachable only through -Ibwt/lbzip2 and defers to the libc macros wherever they already exist.
  • No architecture flags are added. The inverse MTF uses a vector shuffle guarded in the source: vqtbl1q_u8 under __aarch64__ && __ARM_NEON, _mm_shuffle_epi8 under __SSSE3__, scalar otherwise. So aarch64 gets the SIMD path automatically, while a default x86-64 build gets the scalar one unless MOREFLAGS=-march=native (or -mssse3) is passed — the numbers below are from an aarch64 machine, where the SIMD path is live.
  • make DONT_BUILD_LBZIP2=1 disables it; no CI leg needs excluding.

Correctness

bzip2 -t accepts the output and roundtrip is exact on silesia.tar. Checked with no lzbench errors across all 9 levels, -b1 and -b64 chunking, -T4, incompressible random data, and 1- and 10-byte inputs.

Numbers

Apple M5 Max, macOS 26.5, clang 17, lzbench -ebzip2/lbzip2 -t8,8 -o1c4 silesia.tar. Sorted by compressed size, so each level sits next to its bzip2 counterpart:

Compressor name Compression Decompress. Compr. size Ratio
lbzip2 2.6.5 -9 43.4 MB/s 103 MB/s 54570631 25.75
bzip2 1.0.8 -9 25.7 MB/s 76.8 MB/s 54572811 25.75
lbzip2 2.6.5 -8 44.0 MB/s 105 MB/s 54660305 25.79
bzip2 1.0.8 -8 25.5 MB/s 77.7 MB/s 54666392 25.79
lbzip2 2.6.5 -7 43.0 MB/s 107 MB/s 55020087 25.96
bzip2 1.0.8 -7 25.9 MB/s 79.0 MB/s 55030188 25.96
lbzip2 2.6.5 -6 43.5 MB/s 110 MB/s 55353765 26.12
bzip2 1.0.8 -6 26.5 MB/s 80.2 MB/s 55382376 26.13
lbzip2 2.6.5 -5 44.5 MB/s 113 MB/s 55682543 26.27
bzip2 1.0.8 -5 26.8 MB/s 81.5 MB/s 55724395 26.29
lbzip2 2.6.5 -4 44.9 MB/s 118 MB/s 56210660 26.52
bzip2 1.0.8 -4 27.3 MB/s 83.3 MB/s 56265716 26.55
lbzip2 2.6.5 -3 44.8 MB/s 125 MB/s 56925346 26.86
bzip2 1.0.8 -3 27.6 MB/s 86.6 MB/s 56992647 26.89
lbzip2 2.6.5 -2 45.0 MB/s 131 MB/s 57997065 27.36
bzip2 1.0.8 -2 27.9 MB/s 88.5 MB/s 58100593 27.41
lbzip2 2.6.5 -1 44.0 MB/s 133 MB/s 60373170 28.48
bzip2 1.0.8 -1 27.7 MB/s 87.6 MB/s 60484813 28.54

Compression is 1.59-1.73x bzip2's and roughly flat across levels, where bzip2 decays from 27.9 to 25.5 MB/s. Decompression is 1.34-1.52x. Compressed size is equal or marginally smaller: 0.004% at -9, 0.19% at -1.

Compression figures are one iteration per level (a single pass over 212 MB already exceeds the 8 s target); decompression got 2-5 iterations, stable to within ~1%.

lbzip2 is a bzip2-compatible compressor whose command-line tool splits the
work over threads. lzbench benchmarks buffer-to-buffer calls and does its own
threading, so the wrapper drives lbzip2's low-level encoder and decoder
sequentially, block by block, the way compress.c and expand.c do around their
scheduler.

Only the codec sources are vendored (crctab.c, decode.c, divbwt.c, encode.c,
parse.c), unmodified; the tool's threading and I/O machinery is not built. Two
-D renames keep the link clear of zstd's divbwt() and of any other xmalloc(),
and a small arpa/inet.h shim covers MinGW, which lacks that header.

The output is bzip2: bzip2 -t accepts it, and on silesia.tar the compressed
size is within 0.005% of bzip2's at -9.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant